/**
 * User: Oleksii Savchenko
 * Date: 12.02.13
 * Time: 10:45
 */
describe('Check methods of facade on top of W3C DOM API', function(){

    beforeEach (function(){
        this.elem = document.createElement("div");
        this.elem.setAttribute("id", "elementId");
        document.getElementsByTagName("body")[0].appendChild(this.elem);
    });
    afterEach (function(){
        document.getElementsByTagName("body")[0].removeChild(this.elem);
    });

    describe('Check for exists main method of zdom', function(){
        it('Can call check for get dom element', function(){
            expect(zdom('#elementId')._selectedElement).toEqual(this.elem);
        });

        it('should create new dom element with attr', function(){
            var dom_element = zdom('<span>My Facade</span>', {id: "hell-facade", class: "facade", rel: 'box'});

            expect(dom_element._selectedElement.innerHTML).toBe('My Facade');
            expect(dom_element._selectedElement.getAttribute('id')).toBe('hell-facade');
            expect(dom_element._selectedElement.getAttribute('class')).toBe('facade');
            expect(dom_element._selectedElement.getAttribute('rel')).toBe('box');
        });

        it('should get element from this - variable', function(){
            var elem = zdom(this.elem);
            expect(elem._selectedElement).toEqual(this.elem);
        });
    });

    describe('Can to set attribute for dom node', function(){
        beforeEach(function(){
            zdom('#elementId').attr('data-id', 'item_34').attr('class', 'test-class');
        });
        afterEach(function(){
            this.elem.removeAttribute('data-id');
            this.elem.removeAttribute('class');
        });

        it('check for attr in element', function(){
            expect(this.elem.getAttribute('data-id')).toBe('item_34');
            expect(this.elem.getAttribute('data-time')).toBeNull();
            expect(this.elem.getAttribute('class')).toBe('test-class');
            expect(this.elem.getAttribute('class1')).toBeNull();
        });

        it('should get attr from element', function(){
            expect(zdom('#elementId').attr('data-id')).toBe('item_34');
            expect(zdom('#elementId').attr('data-time')).toBeNull();
            expect(zdom('#elementId').attr('class')).toBe('test-class');
            expect(zdom('#elementId').attr('class1')).toBeNull();
        });

        it('should get exception if method call without arguments', function(){
            expect(function(){(zdom('#elementId').attr())}).toThrow('Function call without arguments');
        });
    });

    describe('Can remove attr in element on dome', function(){
        beforeEach(function(){
            this.elem.setAttribute('data-id', 'item_32');
        });
        afterEach(function(){
            this.elem.removeAttribute('data-id');
        });

        it('should delete attr from element', function(){
            expect(this.elem.getAttribute('data-id')).toBe('item_32');
            zdom('#elementId').removeAttr('data-id');
            expect(this.elem.getAttribute('data-id')).toBeNull();
        });

        it('should get exception if method call without arguments', function(){
            expect(function(){(zdom('#elementId').removeAttr())}).toThrow('Function call without arguments');
        });
    });

    describe('Can hide element with delay time', function(){
        beforeEach(function(){
            this.clock = sinon.useFakeTimers();
        });
        afterEach(function(){
            this.clock.restore();
            this.elem.setAttribute("style", "display: block");
        });

        it('Should hide element with delay of hiding', function(){
            zdom('#elementId').hide(800);

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("display");
            expect(display).toBe('block');

            this.clock.tick(800);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("display");
            expect(display).toBe('none');
        });

        it('Should hide element without arguments', function(){
            zdom('#elementId').hide();

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("display");
            expect(display).toBe('block');

            this.clock.tick(0);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("display");
            expect(display).toBe('none');
        });
    });

    describe('Can show element with delay time', function(){
        beforeEach(function(){
            this.clock = sinon.useFakeTimers();
            this.elem.setAttribute("style", "display: none");
        });
        afterEach(function(){
            this.clock.restore();
            this.elem.setAttribute("style", "display: block");
        });

        it('Should show element with delay of hiding', function(){
            zdom('#elementId').show(800);

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("display");
            expect(display).toBe('none');

            this.clock.tick(800);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("display");
            expect(display).toBe('block');
        });

        it('Should show element without arguments', function(){
            zdom('#elementId').show();

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("display");
            expect(display).toBe('none');

            this.clock.tick(0);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("display");
            expect(display).toBe('block');
        });
    });

    describe('Can made visible or hidden element with delay time', function(){
        beforeEach(function(){
            this.clock = sinon.useFakeTimers();
            this.elem.setAttribute("style", "visibility: hidden");
        });
        afterEach(function(){
            this.clock.restore();
            this.elem.setAttribute("style", "visibility: visible;");
        });

        it('Should made visible element with delay of visibility', function(){
            zdom('#elementId').visible(true, 800);

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("visibility");
            expect(display).toBe('hidden');

            this.clock.tick(800);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("visibility");
            expect(display).toBe('visible');
        });

        it('Should made visible element with delay of visibility', function(){

            this.elem.setAttribute("style", "visibility: visible");
            zdom('#elementId').visible(false, 800);

            var cs = window.getComputedStyle(this.elem, "");
            var display = cs.getPropertyValue("visibility");
            expect(display).toBe('visible');

            this.clock.tick(800);

            var cs1 =  window.getComputedStyle(this.elem, "");
            var display = cs1.getPropertyValue("visibility");
            expect(display).toBe('hidden');
        });

    });

    describe('Can append element to html dom', function(){
        beforeEach(function(){
            zdom('<span>My Facade</span>', {id: "hell-facade", class: "facade", rel: 'box'}).appendTo('#elementId');
        });
        afterEach(function(){
            var newElement = document.getElementById('hell-facade');
            this.elem.removeChild(newElement);
        });

        it('check for creating new DOM element', function(){
            expect(zdom('#hell-facade').attr('id')).toBe('hell-facade');
            expect(zdom('#hell-facade').attr('class')).toBe('facade');
            expect(zdom('#hell-facade').attr('rel')).toBe('box');
        });
        it('should get exception, if method call without selector', function(){
            expect(function(){(zdom('<span>My Facade</span>').appendTo())}).toThrow();
        });
    });

    describe('Can get and set html to DOM element', function(){
        beforeEach(function(){
            zdom('<span>My Facade</span>', {id: "hell-facade"}).appendTo('#elementId');
        });
        afterEach(function(){
            var newElement = document.getElementById('hell-facade');
            this.elem.removeChild(newElement);
        });

        it('should get html from element', function(){
            expect(zdom('#hell-facade').html()).toBe('My Facade');
        });
        it('should set html to element', function(){
            zdom('#hell-facade').html('<p>Fary tail about Thumberlina</p>');

            expect(zdom('#hell-facade').html()).toBe('<p>Fary tail about Thumberlina</p>');
        });
    });

    describe('Can parse form for key -> value', function(){

        beforeEach(function(){
            zdom('<form></form>', {id: 'test-form'}).appendTo('#elementId');
        });
        afterEach(function(){
            var newElement = document.getElementById('test-form');
            this.elem.removeChild(newElement);
        });

        it('should return form data object', function(){
            var result = {
                title: 'test',
                product: 'test product'
            };
            zdom('<input>', {
                name: 'title',
                value: 'test'
            }).appendTo('#test-form');
            zdom('<input>', {
                name: 'product',
                value: 'test product'
            }).appendTo('#test-form');

            var dataObj = zdom('#test-form').serializeArray();

            expect(dataObj).toEqual(result);
        });

        it('should return empty form data object', function(){
            var result = {};
            var dataObj = zdom('#test-form').serializeArray();

            expect(dataObj).toEqual(result);
        });

        it('should create data array from existent variables', function(){
            var result = {
                title: 'test'
            };
            zdom('<input>', {
                name: 'title',
                value: 'test'
            }).appendTo('#test-form');
            zdom('<input>', {
                name: 'product',
                value: ''
            }).appendTo('#test-form');
            var dataObj = zdom('#test-form').serializeArray();

            expect(dataObj).toEqual(result);
        });
    });

    describe('Can get and set attribute of form field', function(){
        beforeEach(function(){
            zdom('<form></form>', {id: 'test-form'}).appendTo('#elementId');
        });
        afterEach(function(){
            var newElement = document.getElementById('test-form');
            this.elem.removeChild(newElement);
        });

        it('Should get element from form field', function(){
            zdom('<input>', {
                name: 'title',
                value: 'Test Value',
                id: 'testId'
            }).appendTo('#test-form');

            expect(zdom('#testId').val()).toEqual('Test Value');
        });

        it('Should get empty value from form element', function(){
            zdom('<input>', {
                name: 'title',
                value: '',
                id: 'testId'
            }).appendTo('#test-form');

            expect(zdom('#testId').val()).toBeDefined();
        });

        it('Should set value to form element',function(){
            zdom('<input>', {
                name: 'title',
                value: '',
                id: 'testId'
            }).appendTo('#test-form');

            var setValue = 'my test';
            zdom('#testId').val(setValue);
            var value = document.getElementById('testId').value;

            expect(value).toEqual(setValue);
        });

        it('Should set empty value to form element', function(){
            zdom('<input>', {
                name: 'title',
                value: '',
                id: 'testId'
            }).appendTo('#test-form');

            var setValue = '';
            zdom('#testId').val(setValue);
            var value = document.getElementById('testId').value;

            expect(value).toEqual(setValue);
        });

    });

});